package ch.tiktak.games.powersudoku.solver;

import ch.tiktak.games.powersudoku.GridIsFullException;
import ch.tiktak.games.powersudoku.SudokuGrid;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;

import java.awt.*;
import java.util.LinkedList;
import java.util.List;

public abstract class SudokuSolver {

    protected SudokuGrid originalGrid;

    public SudokuSolver(final SudokuGrid grid) {
        this.originalGrid = grid;
        logger = Logger.getLogger(this.getClass().getSimpleName());
        PropertyConfigurator.configure("log4j.properties");
        logger.info("Logger started.");
    }

    abstract public SudokuGrid solve() throws SudokuSolverException;

    /**
     * @param grid a Sudoku grid
     * @return points with no value. x= row, y= column
     */
    public static List<Point> getEmptySquarePoints(SudokuGrid grid) {
        List<Point> result = new LinkedList<Point>();
        for (int i = 1; i < 10; i++) {
            for (int j = 1; j < 10; j++) {
                if (grid.getValue(i, j) == -1) {
                    result.add(new Point(i, j));
                }
            }
        }
        return result;
    }

    /**
     * @param grid Sudoku grid
     * @return A Point. x = rowIndex, y = columnIndex
     * @throws ch.tiktak.games.powersudoku.GridIsFullException when no more empty squares
     */
    public static Point getNextEmptySquarePoint(SudokuGrid grid) throws GridIsFullException {
        boolean found = false;
        Point result = null;
        for (int i = 1; i < 10; i++) {
            for (int j = 1; j < 10; j++) {
                if (grid.getValue(i, j) == -1) {
                    result = new Point(i, j);
                    found = true;
                    break;
                }
            }
            if (found) {
                break;
            }
        }
        if (!found) {
            throw new GridIsFullException();
        }
        return result;
    }

    public static boolean hasNextEmptySquare(SudokuGrid grid) {
        try {
            getNextEmptySquarePoint(grid);
            return true;
        } catch (GridIsFullException e) {
            return false;
        }
    }

    protected  static Logger logger;

}
